//
//  APIProviderManager
//  APP
//
//  Created by Rdxer on 2017/12/11.
//  Copyright © 2017年 Rdxer. All rights reserved.
//

import Foundation
import Moya
import RxSwift
import FastComponent

extension String {
    var urlEscaped: String {
        return self.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) ?? ""
    }
    var urlAndEscaped: String {
        let res = self.split(separator: "&").joined(separator: "%26")
        return res
    }
}

public class APIProviderManager{
    
    static let moyaNetworkActivityPlugin = NetworkActivityPlugin.init(networkActivityClosure: { (type, target) in
        switch type {
        case .began:
            UIApplication.shared.isNetworkActivityIndicatorVisible = true
        case .ended:
            UIApplication.shared.isNetworkActivityIndicatorVisible = false
        }
    })
    
#if DEBUG
    /// DEBUG 才需要  NetworkLoggerPlugin
    static let pluginList:[PluginType] = [
        NetworkLoggerPlugin.init(verbose: true, cURL: true, output: nil, requestDataFormatter: nil, responseDataFormatter: nil),
        moyaNetworkActivityPlugin
    ]
#else
    static let pluginList:[PluginType] = [
        moyaNetworkActivityPlugin
    ]
#endif
    
    /// token
    static func tokenProvider() -> MoyaProvider<TokenApi> {
        let provider = MoyaProvider<TokenApi>(endpointClosure: MoyaProvider.defaultEndpointMapping, requestClosure: MoyaProvider.defaultRequestMapping, stubClosure: MoyaProvider.neverStub, manager: MoyaProvider<TokenApi>.defaultAlamofireManager(), plugins: pluginList, trackInflights: false)
        return provider
    }
    
    /// NotRequiredtoken
    static func makeNotRequiredTokenProvider<T: TargetType>() -> MoyaProvider<T> {
        let provider = MoyaProvider<T>(endpointClosure: MoyaProvider.defaultEndpointMapping, requestClosure: MoyaProvider.defaultRequestMapping, stubClosure: MoyaProvider.neverStub, manager: MoyaProvider<T>.defaultAlamofireManager(), plugins: [NetworkLoggerPlugin.init(verbose: true, cURL: true, output: nil, requestDataFormatter: nil, responseDataFormatter: nil)], trackInflights: false)
        return provider
    }
    
    /// API
    public static func makeProvider<T: TargetType>() -> MoyaProvider<T> {

        let requestClosure = { (endpoint: Endpoint<T>, done: @escaping MoyaProvider.RequestResultClosure) in
            
            let closure = { (endpoint:Endpoint<T>) in
                do {
                    let request = try endpoint.urlRequest()
                    done(.success(request))
                } catch {
                    done(.failure(MoyaError.underlying(error, nil)))
                }
            }
            
            if ServerConfig.token == nil {
                _ =  ServerConfig.tokenAPI
                    .rx
                    .request(TokenApi.Token)
                    .retry(2)
                    .mapJSON()
                    .subscribe(onSuccess: { (resp) in
                        ServerConfig.token = (resp as! [String:String])["token"]
                        
                        var task = endpoint.task
                        switch task {
                        case let .requestParameters(parameters, parameterEncoding):
                            task = Task.requestParameters(parameters: parameters.appendToken, encoding: parameterEncoding)
                        default:break
                        }
                        
                        closure(endpoint.replacing(task: task))
                    }, onError: { (err) in
                        done(.failure(MoyaError.underlying(err, nil)))
                    })
                return
            }else{
                closure(endpoint)
            }
        }
        
        let provider = MoyaProvider<T>.init(endpointClosure: MoyaProvider.defaultEndpointMapping, requestClosure: requestClosure, stubClosure: MoyaProvider.neverStub, callbackQueue: nil, manager: MoyaProvider<TokenApi>.defaultAlamofireManager(), plugins: pluginList, trackInflights: false)
        
        return provider
    }
    
    
}
